﻿using System;
using System.Data.SqlClient;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using CookComputing.XmlRpc;

namespace WLWCustomProviderTemplate
{


    #region MSWLWstructure
    /// <summary>
    /// This struct represents enclosure.
    /// </summary>
    [XmlRpcMissingMapping(MappingAction.Ignore)]
    public struct Enclosure
    {
        public int length;
        public string type;
        public string url;
    }
    /// <summary>
    /// This struct represents source.
    /// </summary>
    [XmlRpcMissingMapping(MappingAction.Ignore)]
    public struct Source
    {
        public string name;
        public string url;
    }

    /// <summary> 
    /// This struct represents user blog.
    /// </summary> 
    [XmlRpcMissingMapping(MappingAction.Ignore)]
    public struct UserBlog
    {
        /// <summary>
        /// Url to blog.
        /// </summary>
        public string url;
        /// <summary>
        /// BlogID, as defined in rsd file - possible collision.
        /// </summary>
        public string blogid;
        /// <summary>
        /// Name of blog.
        /// </summary>
        public string blogName;
    }
    /// <summary> 
    /// This struct represents information about a user. 
    /// </summary> 
    [XmlRpcMissingMapping(MappingAction.Ignore)]
    public struct UserInfo
    {
        /// <summary>
        /// Url to user's blog.
        /// </summary>
        public string url;
        /// <summary>
        /// Blog's unique identifier.
        /// </summary>
        public string blogid;
        /// <summary>
        /// Name of a blog
        /// </summary>
        public string blogName;
        /// <summary>
        /// User's first name.
        /// </summary>
        public string firstname;
        /// <summary>
        /// User's last name.
        /// </summary>
        public string lastname;
        /// <summary>
        /// User's email.
        /// </summary>
        public string email;
        /// <summary>
        /// User's nick name.
        /// </summary>
        public string nickname;
        /// <summary>
        /// User's unique identifier.
        /// </summary>
        public string userid;
    }

    /// <summary> 
    /// This struct represents the information about a category.
    /// </summary> 
    [XmlRpcMissingMapping(MappingAction.Ignore)]
    public struct Category
    {
        public string categoryid;
        public string title;
        public string description;
        public string htmlUrl;
        public string rssUrl;

    }
    /// <summary>
    /// This struct represents a post.
    /// </summary>
    [XmlRpcMissingMapping(MappingAction.Ignore)]
    public struct Post
    {
        /// <summary>
        /// date of creation of current post
        /// </summary>
        public DateTime dateCreated;
        /// <summary>
        /// Description of the post- this is content of post.
        /// </summary>
        public string description;
        /// <summary>
        /// Post's title
        /// </summary>
        public string title;
        /// <summary>
        /// Unique identifier of a post.
        /// </summary>
        public string postid;
        /// <summary>
        /// Array of assigned categories.
        /// </summary>
        public string[] categories;
        /// <summary>
        /// Link (url) to post.
        /// </summary>
        public string link;
        /// <summary>
        /// Permalink to post.
        /// </summary>
        public string permaLink;
        /// <summary>
        /// Unique identifier of a user that created that post (usually that is author).
        /// </summary>
        public string userid;
        /// <summary>
        /// Post's enclosure.
        /// </summary>
        public Enclosure enclosure;
        /// <summary>
        /// Post's source.
        /// </summary>
        public Source source;
    }
    /// <summary>
    /// Struct that represents a certain media object for example image, video or sound.
    /// Note that this stucture can represent any file type (even an exe)
    /// but handling of such files is never intended (maybe there is a wlw plugin that can 'attach' other files to post).
    /// </summary>
    [XmlRpcMissingMapping(MappingAction.Ignore)]
    public struct MediaObject
    {
        /// <summary>
        /// Filename of a file that user selected.
        /// </summary>
        public string name;
        /// <summary>
        /// Type of a file in MIME type format.
        /// </summary>
        public string type;
        /// <summary>
        /// Bits field contains array of bites that file(Media Object) contains.
        /// </summary>
        public byte[] bits;
    }
    /// <summary>
    /// Struct that represents a Media Object informations.
    /// </summary>
    [XmlRpcMissingMapping(MappingAction.Ignore)]
    public struct MediaObjectInfo
    {
        /// <summary>
        /// File name of stored file.
        /// </summary>
        public string file;
        /// <summary>
        /// Url from which file can be retrieved.
        /// </summary>
        public string url;
        /// <summary>
        /// Type of a file in MIME type format.
        /// </summary>
        public string type;
    }
    #endregion
    /// <summary>
    /// Summary description for xmlrpc.
    /// </summary>
    [XmlRpcService(Name = "$safeprojectname$ weblog API", Description = "Description of service", AutoDocumentation = true)]
    [XmlRpcUrl("$safeprojectname$/xmlrpc.ashx")]
    public class xmlrpc : XmlRpcService
    {
        /// <summary> 
        /// Returns the most recent draft and non-draft blog posts sorted in descending order by publish date. 
        /// </summary> 
        /// <param name="blogid"> Unique identifier that identifies specific user blog as account. </param> 
        /// <param name="username"> User's username. </param> 
        /// <param name="password"> User's password. </param> 
        /// <param name="numberOfPosts"> The number of posts to return. </param> 
        /// <returns>Array of Posts</returns> 
        [XmlRpcMethod("metaWeblog.getRecentPosts")]
        public Post[] getRecentPosts(string blogid, string username, string password, int numberOfPosts)
        {
            #region MSWLWgetRecentPosts
            int userID = checkUser(username, password);
            if (userID != -1)
            {
                Post[] returnMe = new Post[numberOfPosts];
                //TODO: please complete this code!
                throw new XmlRpcFaultException(0, "not yet implemented");
                return returnMe;
            }
            else
            {
                throw new XmlRpcFaultException(0, "invalid user credentials");
            }
            #endregion
        }

        /// <summary> 
        /// Posts a new post(entry) to a blog.
        /// </summary>
        /// <param name="blogid"> Unique identifier that identifies specific user blog as account. </param> 
        /// <param name="username"> User's username. </param> 
        /// <param name="password"> User's password. </param> 
        /// <param name="post"> A struct representing the content(entry) to post to blog (upload). </param> 
        /// <param name="publish"> True if post should be published immediately, else this post will be uploaded and marked as draft.</param> 
        /// <returns> Postid of the created post entry. </returns> 
        [XmlRpcMethod("metaWeblog.newPost")]
        public string newPost(string blogid, string username, string password, Post content, bool publish)
        {
            #region MSWLWnewPost
            int userID = checkUser(username, password);
            if (userID != -1)
            {
                string returnMe= "null";
                //TODO: please complete this code!
                throw new XmlRpcFaultException(0, "not yet implemented");
                return returnMe;
            }
            else
            {
                throw new XmlRpcFaultException(0, "invalid user credentials");
            }
            #endregion
        }

        /// <summary> 
        /// Edits an existing entry on a blog. 
        /// </summary> 
        /// <param name="postid"> Unique identifier of the post to update. </param> 
        /// <param name="username"> User's username. </param> 
        /// <param name="password"> User's password. </param> 
        /// <param name="post"> A struct representing the content(entry) to post to blog (upload). </param> 
        /// <param name="publish"> True if post should be published immediately, else this post will be uploaded and marked as draft.</param> 
        /// <returns> Always returns true. </returns> 
        [XmlRpcMethod("metaWeblog.editPost")]
        public bool editPost(string postid, string username, string password, Post content, bool publish)
        {
            #region MSWLWeditPost
            if (checkUser(username, password) != -1)
            {
                //TODO: please complete this code!
                throw new XmlRpcFaultException(0, "not yet implemented");
            }
            else
            {
                throw new XmlRpcFaultException(0, "invalid user credentials");
            }
            return true;
            #endregion
        }

        /// <summary> 
        /// Deletes a post from the blog. 
        /// </summary> 
        /// <param name="appKey"> This parameter is ignored. </param> 
        /// <param name="postid"> Unique identifier of the post to update. </param> 
        /// <param name="username"> User's username. </param> 
        /// <param name="password"> User's password. </param> 
        /// <param name="post"> A struct representing the content(entry) to post to blog (upload). </param> 
        /// <param name="publish"> This parameter is ignored. </param> 
        /// <returns> Always returns true. </returns> 
        [XmlRpcMethod("blogger.deletePost")]
        public bool deletePost(string appKey, string postid, string username, string password, bool publish)
        {
            #region MSWLWdeletePost
            if (checkUser(username, password) != -1)
            {
                //TODO: please complete this code!
                throw new XmlRpcFaultException(0, "not yet implemented");
            }
            else
            {
                throw new XmlRpcFaultException(0, "invalid user credentials");
            }
            return true;
            #endregion
        }

        /// <summary> 
        /// Returns information about the user’s weblog account. User can have many blogs or he can have none. 
        /// Note that one user can have many blogs and single blog can have many posts.
        /// </summary> 
        /// <param name="appKey"> This parameter is ignored. </param> 
        /// <param name="username"> User's username. </param>
        /// <param name="password"> User's password. </param> 
        /// <returns> Array of structs that represents user’s blogs. Using WLW user can select blog on which he wants to post</returns> 
        [XmlRpcMethod("blogger.getUsersBlogs")]
        public UserBlog[] getUsersBlogs(string appKey, string username, string password)
        {
            #region MSWLWgetUsersBlogs
            UserBlog returnMe;
            //TODO: please complete this code!
            //NOTE: user credentials are not checked here because
            //      user's blog list is retrieved using username 
            //      and password as DB filters. Feel free to use 
            //      checkUser( ) method.
            throw new XmlRpcFaultException(0, "not yet implemented");
            return new UserBlog[1] { returnMe };
            #endregion
        }

        /// <summary> 
        /// Returns user info.
        /// </summary> 
        /// <param name="appKey"> This parameter is ignored. </param> 
        /// <param name="username"> User's username. </param>
        /// <param name="password"> User's password. </param> 
        /// <returns> Struct that contains profile information about the user.</returns> 
        [XmlRpcMethod("blogger.getUserInfo")]
        public UserInfo getUserInfo(string appKey, string username, string password)
        {
            #region MSWLWgetUserInfo
            UserInfo returnMe;
            //TODO: please complete this code!
            //NOTE: user credentials are not checked here because
            //      user info is retrieved using username and
            //      password as DB filters. Feel free to use 
            //      checkUser( ) method.
            throw new XmlRpcFaultException(0, "not yet implemented");
            return returnMe;
            #endregion
        }

        /// <summary> 
        /// Returns a specific post(entry) from a blog. 
        /// </summary> 
        /// <param name="postid"> The ID of the post to update. </param> 
        /// <param name="username"> User's username. </param>
        /// <param name="password"> User's password. </param> 
        /// <returns> Always returns true. </returns> 
        [XmlRpcMethod("metaWeblog.getPost")]
        public Post getPost(string postid, string username, string password)
        {
            #region MSWLWgetPost
            int userID = checkUser(username, password);
            if (userID != -1)
            {
                //TODO: please complete this code!
                throw new XmlRpcFaultException(0, "not yet implemented");
            }
            else
            {
                throw new XmlRpcFaultException(0, "invalid user credentials");
            }
            #endregion
        }

        /// <summary> 
        /// Get the array of categories that have been used in the blog. 
        /// </summary> 
        /// <param name="blogid"> Unique identifier that identifies specific user blog as account. </param> 
        /// <param name="username"> User's username. </param>
        /// <param name="password"> User's password. </param>
        /// <returns> An array of structs that represents each category.</returns> 
        [XmlRpcMethod("metaWeblog.getCategories")]
        public Category[] getCategories(string blogid, string username, string password)
        {
            #region MSWLWgetCategories
            Category returnMe;
            int userID = checkUser(username, password);
            if (userID != -1)
            {
                //TODO: please complete this code!
                throw new XmlRpcFaultException(0, "not yet implemented");
            }
            else
            {
                throw new XmlRpcFaultException(0, "invalid user credentials");
            }
            return new Category[1] { returnMe };
            #endregion
        }
        /// <summary> 
        /// Method that accepts remote file and saves it on the server.
        /// </summary>
        /// <param name="blogid"> Unique identifier that identifies specific user blog as account. </param>
        /// <param name="username"> User's username. </param>
        /// <param name="password"> User's password. </param>
        /// <param name="mediaObject"> Struct that represents media object that needs to be uploades</param>
        /// <returns>Struct that contains information about newly uploaded file</returns>
        [XmlRpcMethod("metaWeblog.newMediaObject")]
        public MediaObjectInfo newMediaObject(string blogid, string username, string password, MediaObject mediaObject)
        {
            #region MSWLWNewMediaObject
            MediaObjectInfo returnMe;
            int userID = checkUser(username, password);
            if (userID != -1)
            {
                //TODO: please complete this code!
                throw new XmlRpcFaultException(0, "not yet implemented");
            }
            else
            {
                throw new XmlRpcFaultException(0, "invalid user credentials");
            }
            return returnMe;
            #endregion
        }
        /// <summary>
        /// This method verifies given username and password
        /// </summary>
        /// <param name="username"> User's username. </param>
        /// <param name="password"> User's password. </param>
        /// <returns> Valid userID/blogID else it returns -1</returns>
        private int checkUser(string username, string password)
        {
            #region MSWLWcheckUser
            int returnMe = -1;
            //TODO: please complete this code!
            throw new XmlRpcFaultException(0, "not yet implemented");
            return returnMe;
            #endregion
        }
        /// <summary>
        /// This method strips all html code from input string,
        /// it is here because you may find it usefull.
        /// </summary>
        /// <param name="input">Input string that has html code in it</param>
        /// <param name="fileUrl">ref parameter that is filled with first file url</param>
        /// <returns> String that contains no html code</returns>
        private string stripHtml(string input, ref string fileUrl)
        {
            #region MSWLWstripHtml
            //This method is left in this template because tested weblog system only publishes text.
            string temp = input;
            MatchCollection col = Regex.Matches(temp, "src=\".*\\.[A-Za-z]{3,4}\"");
            fileUrl = col[col.Count - 1].Value;
            if (fileUrl.Length < 9)
            {
                fileUrl = "~/images/imgNoImage.jpg";
            }
            temp = temp.Replace("</p>", "</p>" + Environment.NewLine);
            temp = temp.Replace("&#160;", Environment.NewLine); //&#160; => this is wlw new line string.
            temp = Regex.Replace(temp, @"<(.|\n)*?>", string.Empty);
            return temp;
            #endregion
        }
    }
}
